package _02_linked_list.exerc;

import java.util.Iterator;
import java.util.StringJoiner;

/**
 * @author: mornd
 * @dateTime: 2023/6/2 - 15:25
 */
public class ListNode implements Iterable<Integer> {
    public int val;
    public ListNode next;

    public ListNode() {
    }

    public ListNode(int val) {
        this.val = val;
    }

    public ListNode(ListNode next) {
        this.next = next;
    }

    public ListNode(int val, ListNode next) {
        this.val = val;
        this.next = next;
    }

    @Override
    public int hashCode() {
        int r = 0;
        for (Integer i : this) {
            r += 31 * i;
        }
        return r;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof ListNode)) return false;
        ListNode listNode = (ListNode) o;
        ListNode that = this;

        while (that.val == listNode.val) {
            that = that.next;
            listNode = listNode.next;
            if(that == null && listNode == null) {
                return true;
            }
            if(that == null || listNode == null) {
                return false;
            }
        }
        return false;
    }

    @Override
    public String toString() {
        StringJoiner joiner =
                new StringJoiner(",", "[", "]");

        for (Integer i : this) {
            joiner.add(String.valueOf(i));
        }
        return joiner.toString();

//        StringBuilder sb = new StringBuilder("[");
//        for (ListNode n = this; n != null; n = n.next) {
//            sb.append(n.val);
//            if (n.next != null) {
//                sb.append(",");
//            }
//        }
//        return sb.append("]").toString();
    }

    /**
     * 将数组元素填充到链表中
     *
     * @param arr
     * @return
     */
    public static ListNode of(int[] arr) {
        ListNode head = null;
        ListNode tail = null;
        for (int v : arr) {
            ListNode t = new ListNode(v);
            if (head == null) {
                head = tail = t;
            } else {
                tail.next = t;
                tail = t;
            }
        }
        return head;
    }

    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            private ListNode p = ListNode.this;
            @Override
            public boolean hasNext() {
                return p != null;
            }

            @Override
            public Integer next() {
                ListNode r = p;
                p = p.next;
                return r.val;
            }
        };
    }
}
